﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace CAD_Project_1
{
    class Bdr
    {
        private string[] args;
        private Initiate ini;        

        /** 
         * Construtor da classe. recebe o parametro args que sao os campos
         * introduzidos na linha de comando.
         */
        public Bdr(string[] args)
        {
            this.args = args;
            this.ini = new Initiate(args);
        }

        /** 
         * Funcao que lanca a execucao do programa         
         */
        public void bdrExecute()
        {
            //organiza os parametros de entrada.
            ini.organiseParameters();

            Console.WriteLine("Project Name:" + ini.PName);
            Console.WriteLine("Name File:" + ini.FFile);
            Console.WriteLine("File Diff:" + ini.ModeDiff);
            Console.WriteLine("URL:" + ini.UUrl);
            Console.WriteLine("Log:" + ini.PLog);
            Console.WriteLine("Xml File:" + ini.XmlFile);
            Console.WriteLine("Test mode:" + ini.PTest);
            Console.WriteLine("Gunzip:" + ini.GName);

            //verifica se o campos obrigatorios estao preenhidos.
            if (ini.PName.CompareTo(String.Empty) != 0 &&
                ini.FFile.CompareTo(String.Empty) != 0)
            {
                //verifica se o projecto ja existe
                if (!directoryExist(ini.PName) ||
                    !fileExist(ini.PName, ini.FFile))
                {                    
                    //Cria a directoria                                        
                    createDirectory(ini.PName);
                    ini.newLog();

                    //verifica se o comando url
                    if (ini.UUrl.CompareTo(string.Empty) != 0)
                    {
                        //Faz o download do ficheiro                        
                        downloadFile(ini.UUrl, ini.FFile);
                        renameGZ(ini.FFile);
                    }
                    //verifica se o comando gunzip esta a ser chamado
                    if (ini.GName.CompareTo(string.Empty) != 0)
                    {
                        unzipFile(ini.FFile);
                    }

                    if (ini.ModeDiff.CompareTo(string.Empty) != 0)
                    {
                        diff(ini.PName, ini.ModeDiff, ini.FFile);
                    }

                    //inicia a funcionalidade relacionada ao XML
                    if (ini.XmlFile.CompareTo(string.Empty) != 0)//CRIAR SCRIPT BD
                    {
                        DatabaseScripts ds = new DatabaseScripts(ini);
                        ds.generate_SQLDB_TableScript();
                    }

                    
                }
                //verifica se o comando gunzip esta a ser chamado
                else if (ini.GName.CompareTo(string.Empty) != 0 &&
                    ini.UUrl.CompareTo(string.Empty) == 0)
                {                    
                    ini.newLog();
                    changeDirectory(ini.PName);
                    unzipFile(ini.FFile);
                }
                ////verifica se o comando diff esta a ser chamado
                //else if (ini.ModeDiff.CompareTo(string.Empty) != 0)
                //{
                //    Console.WriteLine("aqui2");
                //    ini.newLog();
                //    if (ini.UUrl.CompareTo(string.Empty) != 0)
                //    {
                //        downloadFile(ini.UUrl, ini.FFile);

                //        if (ini.GName.CompareTo(string.Empty) != 0)
                //        {
                //            renameGZ(ini.FFile);
                //            unzipFile(ini.FFile);                            
                //        }
                //    }
                //    diff(ini.PName, ini.ModeDiff, ini.FFile);
                //}
                //inicia a funcionalidade relacionada ao XML
                else if (ini.XmlFile.CompareTo(string.Empty) != 0)
                {
                    DatabaseScripts ds = new DatabaseScripts(ini);
                    ds.generate_SQLDB_TableScript();

                }
                else
                {
                    System.Console.WriteLine("The File already exists. " +
                    "Please press any key to exit!");
                    System.Console.ReadLine();
                }
            }
            else
            {
                System.Console.WriteLine("Must have -p nameProject -f nameFile."
                    + "Please press any key to exit!");
                System.Console.ReadLine();
            }
            try
            {
                ini.closeLog();
            }
            catch (Exception ex)
            {
            }
        }

        private Boolean directoryExist(string directory)
        {
            string fullPath;
            fullPath = Directory.GetCurrentDirectory() + "\\" + directory;

            if (Directory.Exists(fullPath))
                return true;
            else
                return false;
        }

        private Boolean fileExist(string directory, string filename)
        {
            string fullPath;
            string aux = filename.Replace(".gz", "") + "_" +
                    DateTime.Today.Year + DateTime.Today.Month +
                    DateTime.Today.Day + ".gz";

            Console.WriteLine(aux);

            fullPath = Directory.GetCurrentDirectory() + "\\" + directory +
                "\\" + aux;
            if (File.Exists(fullPath))
                return true;
            else
                return false;
        }

        private void createDirectory(string argument)
        {
            if (!ini.PTest)
            {
                string fullPath;
                fullPath = Directory.GetCurrentDirectory() + "\\" + argument;
                Directory.CreateDirectory(fullPath);
                changeDirectory(argument);
            }
        }

        private void changeDirectory(string argument)
        {
            Directory.SetCurrentDirectory(Directory.GetCurrentDirectory() +
                "\\" + argument);
        }

        private void downloadFile(string url, string filename)
        {
            //ini.writeLog("Initiate Download " + DateTime.Now);
            Stopwatch stop = new Stopwatch();
            if (!ini.PTest)
            {
                string path;                
                ini.closeLog();
                path = "wget";
                Process process = new Process();                
                process.StartInfo.FileName = path;
                if (ini.PLog)
                {
                    process.StartInfo.Arguments = url + filename + " -a " + ini.LogFile.Path;
                }
                else
                {
                    process.StartInfo.Arguments = url + filename;
                }
                process.StartInfo.CreateNoWindow = false;
                process.StartInfo.UseShellExecute = false;                
                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                stop.Start();
                process.Start();
                process.WaitForExit();
                process.Close();

                
                if (ini.PLog)
                {
                    StreamReader sr = new StreamReader(ini.Path);
                    char[] separators = { '(', ')' };
                    string[] aux = sr.ReadToEnd().Split(separators);
                    sr.Close();
                    //ini.writeLog("End Download " + DateTime.Now);
                    FileInfo file = new FileInfo(filename);
                    Console.WriteLine("DOWNLOAD|" + filename + "|" +
                        stop.ElapsedMilliseconds / 1000 + "|" + stop.Elapsed +
                        "|(" + aux[3] + ")|" + (file.Length / 1024) / 1024 + " (in MB)");
                    ini.newLog(true);
                }                
            }
            else
            {
                Console.WriteLine("DOWNLOAD|" + filename + "|" +
                    stop.ElapsedMilliseconds / 1000 + "|" + stop.Elapsed +
                    "|(infinit)| X (in MB)");
            }            
        }

        private void diff(string projectName, string diffFile, string filename)
        {

            Stopwatch stop = new Stopwatch();
            if (!ini.PTest)
            {
                StreamWriter sw = new StreamWriter(projectName + ".txt");
                string path = "diff";
                Process process = new Process();
                process.StartInfo.FileName = path;
                //process.StartInfo.Arguments = ".\\" + projectName + "\\" + diffFile
                process.StartInfo.Arguments = ".\\" + diffFile
                    + " " + filename.Replace(".gz","");
                process.StartInfo.CreateNoWindow = false;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                stop.Start();
                process.Start();

                sw.WriteLine(process.StandardOutput.ReadToEnd());
                sw.Flush();
                sw.Close();

                process.WaitForExit();
                process.Close();
                stop.Stop();

                FileInfo filebase = new FileInfo(filename);
                //FileInfo file = new FileInfo(projectName + "\\" + diffFile);
                FileInfo file = new FileInfo(".\\" + diffFile);
                FileInfo diff = new FileInfo(projectName + ".txt");

                string log = "DIFF:file (" + (file.Length / 1024) / 1024 +
                    " MB):base file (" + (filebase.Length / 1024) / 1024 +
                    " MB):diff file (" + (diff.Length / 1024) / 1024 + " MB)";

                Console.WriteLine(log);
                ini.writeLog(log);
            }
            else 
            {
                Console.WriteLine("DIFF:file ( X MB):base file ( X MB):diff file ( X MB)");
            }
        }

        private void unzipFile(string archive)
        {                        
            Stopwatch stop = new Stopwatch();
            if (!ini.PTest)
            {
                string path;
                path = "7z";
                Process process = new Process();
                process.StartInfo.FileName = path;
                process.StartInfo.Arguments = "e " + archive;
                process.StartInfo.CreateNoWindow = false;
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                stop.Start();
                process.Start();
                process.WaitForExit();
                process.Close();
                stop.Stop();

                archive = renameHost();

                FileInfo fi = new FileInfo(archive);
                string[] filename = archive.Split('.');
                FileInfo fu = new FileInfo(filename[0]);

                string log = "7z|" + archive + "|" + stop.Elapsed + " |" +
                    (fi.Length / 1024) / 1024 + "MB|" + (fu.Length / 1024) / 1024 +
                    "MB";

                ini.writeLog(log);
                System.Console.WriteLine(log);
            }
            else 
            {
                Console.WriteLine("7z|" + archive + "|" + stop.Elapsed +
                    " | X MB| X MB");
            }


        }

        private void renameGZ(string filename) {
            if (!ini.PTest)
            {
                string aux = filename.Replace(".gz", "") + "_" +
                        DateTime.Today.Year + DateTime.Today.Month +
                        DateTime.Today.Day + ".gz";
                if (File.Exists(filename))
                {
                    File.Move(filename, aux);
                    File.Delete(filename);
                }
                else
                    Console.WriteLine("File don t exist.");
                ini.FFile = aux;
            }
        }

        private string renameHost()
        {
            if (!ini.PTest)
            {
                string aux = "host_" +
                        DateTime.Today.Year + DateTime.Today.Month +
                        DateTime.Today.Day;
                if (File.Exists("host"))
                {
                    File.Move("host", aux);
                    File.Delete("host");
                }
                else
                    Console.WriteLine("File don t exist");
                return aux;
            }
            return "";
        }
    }
}
